#ifndef TEMPLATE_STUDY_H_
#define TEMPLATE_STUDY_H_
#include <string>
#include <vector>

#include "excpt_study.h"

using namespace std;

template <typename T>

T max1(T a, T b)
{
    return a >= b ? a : b;
}

class Integer
{
private:
    int i;

public:
    Integer(int i)
    {
        this->i = i;
    }
    string toString()
    {
        return to_string(i);
    }
    bool operator>=(Integer integer)
    {
        return this->i >= integer.i;
    }
};

template <typename D>
class Tree
{
private:
    D *data;
    Tree<D> *left;
    Tree<D> *right;

public:
    Tree()
    {
        this->data = nullptr;
        this->left = nullptr;
        this->left = nullptr;
    }

    void put(D *data)
    {
        if (this->data == nullptr)
        {
            this->data = data;
        }
        else if (*(this->data) >= *data)
        {
            if (left == nullptr)
            {
                left = new Tree<D>();
            }
            left->put(data);
        }
        else
        {
            if (right == nullptr)
            {
                right = new Tree<D>();
            }
            right->put(data);
        }
    }

    string toString()
    {
        return "[left=" + (left == nullptr ? "NULL" : left->toString()) + ", data=" + (data == nullptr ? "NULL" : data->toString()) + ",right=" + (right == nullptr ? "NULL" : right->toString()) + "]";
    }
};

template <typename T, typename U>
class Pair
{
public:
    T first;
    U second;
    Pair(T f, U s) : first(f), second(s)
    {
    }
    void print()
    {
        cout << "First: " << first << ", Second: " << second << endl;
    }
};

template <typename T, int Size>
class FixedArray
{
private:
    T datas[Size];

public:
    FixedArray()
    {
    }
    T &operator[](int index)
    {
        if (index >= Size)
        {
            throw ArrayOutOfIndexException("数组越界错误");
        }
        return datas[index];
    }
    int size() const
    {
        return Size;
    }
};

template <template <typename> class Container, typename T>
class Wrapper
{
private:
    Container<T> container;

public:
    void add(const T &value)
    {
        container.push_back(value);
    }
    void print()
    {
        for (const auto &item : container)
        {
            cout << item << " ";
        }
        cout << endl;
    }
};

template <typename... types>
class Tuple;

template <>
class Tuple<>
{
};

template <typename Head, typename... Tail>
class Tuple<Head, Tail...> : private Tuple<Tail...>
{
public:
    Head value;
    Tuple(Head head, Tail... t) : value(head), Tuple<Tail...>(t...) {}
    template <int N>
    auto get() const
    {
        if constexpr (N == 0)
        {
            return value;
        }
        else
        {
            return Tuple<Tail...>::template get<N - 1>();
        }
    }
};

template <typename T = int, typename U = double, int N = 10>
class ConfigurableContainer
{
private:
    T array[N];
    U default_value;

public:
    ConfigurableContainer(U u = U{}) : default_value(u) {}
};

template <typename _Tp>

struct equal_to1 : public equal_to<_Tp>
{
    bool
    operator()(const _Tp &__x, const _Tp &__y) const
    {
        return __x == __y;
    }
};

template <>

struct equal_to1<string>
{
    bool
    operator()(const string &__x, const string &__y) const
    {
        return __x == __y;
    }
};

template <typename K, typename V, typename Equal = equal_to1<K>>
class SimpleMap
{
private:
    vector<pair<K, V>> data;
    Equal equal;

public:
    void insert(const K &key, const V &value)
    {
        data.emplace_back(key, value);
    }

    V *find(const K &key)
    {
        for (auto &entry : data)
        {
            if (equal(entry.first, key))
            {
                return &entry.second;
            }
        }
        return nullptr;
    }
};

//完美转发
template<typename T, typename Arg>
T create(Arg&& arg){
    return T(forward<Arg>(arg));
}



#endif